home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
QRZ! Ham Radio 6
/
QRZ Ham Radio Callsign Database - Volume 6.iso
/
mac
/
files
/
amiga
/
csrc720j.lzh
/
samiga.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-04-17
|
16KB
|
621 lines
/*
* SAMIGA.C - 19th Aug 1988 - System dependent functions for the
* single-user SYSOP version of 'mb'.
* Pete Hardie VE5VA
*
*/
#include "mb.h"
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#include <graphics/text.h>
#include <ctype.h>
#include <time.h>
#include "rexxhostbase.h"
extern struct RexxHost *rexx_host;
extern long rexxbit;
char arexx_port_name[50];
char *arexx_port = 0L;
extern struct Window *mywindow;
extern struct IntuiMessage *NewMessage;
short debug;
char tmpstr[300];
extern struct IOStdReq *Con_Read,*Con_Write;
extern char optflags[];
char l_date[7], l_time[5];
char z_date[7], z_time[5];
char pt_flag = 0;
short done_flag = 1;
/*
* Set the current I/O device.
*/
ioport(pp)
PORTS *pp;
{
port = pp;
}
/*
* Return non-zero if a character waits at current input.
*/
instat()
{
register int st;
/* check for char at console */
if(CheckIO((struct IORequest *)Con_Read))return(1);
return(0);
}
/*
* Put the character out the current port,
* echo to console if the current port is not the console.
* Note special handling of end-of-line character.
*/
outchar(ch)
char ch;
{
if (ch is '\r') return;
if (ch is '\n') ch = '\r';
/*
* Put it out to the console, if it is going there.
*/
if ((port->dev is p_console) or port->ec) {
if (ch is '\r') ttputc('\n');/* output '\n' */;
ttputc(ch);
}
}
#define PROCLEN 200
unsigned char procstr[PROCLEN];
outstr(cp)
unsigned char *cp;
{
register unsigned char *p,*q;
register int beepcount;
if(debug) {
p = cp;
while(*p)outchar(*p++);
return;
}
if(arexx_port) {
remnl(cp);
if(debug)printf("Send '%s' to '%s'\n",cp,arexx_port);
SendRexxMsg((STRPTR)arexx_port,0L,(STRPTR)cp,0L);
return;
}
/* count the number of beeps in the line so that we can give an audible
as well as visual beep
*/
if((port->dev is p_console) || port->ec) {
beepcount = 0;
for(q = cp,p = &procstr[0];*q && p < &procstr[PROCLEN-1];q++) {
if(*q is '\r')continue;
*p++ = *q;
if(*q == '\007')beepcount++;
}
*p = 0;
Con_Write->io_Data = (APTR) &procstr[0];
Con_Write->io_Length = p-&procstr[0];
Con_Write->io_Command = CMD_WRITE;
DoIO((struct IORequest *)Con_Write);
while(beepcount--) {
beep();
Delay(15L);
}
}
}
/* samiga can't talk to the tnc! */
PORTS *devtnc = 0L;
char *inittnc(infile)
char *infile;
{
return((char *)0);
}
/*
hex(c)
char c;
{
register char k;
k = c;
if((k >= '0') && (k <= '9'))return(k - '0');
k = toupper(k);
if((k >= 'A') && (k <= 'F'))return(k - 'A' + 10);
return(0);
}
*/
flipdebug()
{
debug ^= 1;
if(debug) {
ttputs("debug now ON\n");
}
else {
ttputs("debug now OFF\n");
}
}
extern unsigned char ichar;
extern long keybit,windbit,timerbit;
long getbits;
struct timeRequest {
struct IORequest tr_node;
struct timeval tr_time;
};
extern struct timeRequest timermsg;
/* replace the original do_idle because it busy-waited ...
this version sleeps until there is something to do
*/
extern short cursecs;
do_idle()
{
register unsigned char ch,*q;
register PORTS *p;
int curmin,curmon;
ULONG class,waitbits;
char go_flag;
USHORT code;
struct RexxMsg *rexxmessage; /* incoming rexx messages */
STRPTR Arg; /* Temporary string pointer */
arexx_port = 0L;
cursor_off();
for(p=porthd; p != NULL; p = p->next) {
p->ec = p->ecmon;
}
ioport(cport);
/* figure out time to next forward and set timer */
curtim();
curmin = 60 - cursecs;
settimer(curmin);
/* There might already be an unread char at the serial or console port */
clrbusy();
waitbits = windbit | timerbit | keybit | rexxbit;
ttputs("\nIDLE\n");
while(1) {
getbits = Wait(waitbits);
go_flag = 0;
/* Although SYSOP has an AREXX port open it does not take commands
from other AREXX ports. It only gives them
*/
if(rexxbit & getbits) {
while(rexxmessage = GetRexxMsg(rexx_host,0L)) {
if(Arg = GetRexxCommand(rexxmessage)) {
if(!strncmp((char *)Arg,"GO",2)) {
go_flag++;
q = (unsigned char *)Arg + 2;
while((*q == ' ') || (*q == '\n'))q++;
if(*q) {
strcpy(arexx_port_name,(char *)q);
arexx_port = arexx_port_name;
}
else {
arexx_port = 0L;
}
}
ReplyRexxCommand(rexxmessage,0L,0L,0L);
if(go_flag)goto cmd_exit;
}
else {
FreeRexxCommand(rexxmessage);
}
}
}
if(windbit & getbits) {
while(NewMessage =
(struct IntuiMessage *)GetMsg(mywindow->UserPort)) {
class = NewMessage->Class;
code = NewMessage->Code;
ReplyMsg((struct Message *)NewMessage);
if(class == CLOSEWINDOW) {
/* say a fond farewell, don't ask fer sure? */
if(done_flag) {
if(timerbit & getbits) {
WaitIO((struct IORequest *)&timermsg);
}
else {
cantimer();
}
SetWindowTitles(mywindow,(UBYTE *)"",(UBYTE *) -1L);
/* Need this to cancel out the clrbusy in done() */
setbusy();
done(1);
}
}
}
}
if(getbits & keybit) {
WaitIO((struct IORequest *)Con_Read);
ch = ichar;
Con_Read->io_Data = (APTR)&ichar;
Con_Read->io_Command = CMD_READ;
Con_Read->io_Length = 1;
SendIO((struct IORequest *)Con_Read);
if(ch == wchar) {
cmd_exit:
ioport(cport);
cursor_on();
/* could have a timerbit set here.
readbit could also be set but must handle that a
different way.
*/
if(timerbit & getbits) {
WaitIO((struct IORequest *)&timermsg);
}
else {
cantimer();
}
return;
}
if(ch == '\033') {
ttputs("do_idle\n");
}
}
/* This code is deliberately placed last. If a timer bit occurs
at the same time as a character arrives from the serial port
then this code will hang the serial port up because afwd()
tries to use the port again without clearing the existing char.
So workaround it. Putting the timer code here guarantees that
even if the ser char did occur it will be handled first and the
ser char code handles the problem of returning from this routine
with a timer bit set.
*/
if(timerbit & getbits) {
WaitIO((struct IORequest *)&timermsg);
curtim();
curmin = 10 * (l_time[2] - '0') + (l_time[3] - '0');
curmon = 10 * (l_date[2] - '0') + (l_date[3] - '0');
settimer(60);
}
}
}
/* replace getdat from mbutil to reduce busy waits */
/* MAXLEN is the longest unterminated line the justification routine
will accept before it rips out the word and keeps it for later use.
MAXJUST is the longest word that the routine will keep ... if the word
is any longer than this then it will just allow you to mess up the line!
*/
#define MAXLEN 77
#define MAXJUST 20
unsigned char x_pos = 0; /* Position on line for right justification */
unsigned char s_pos = 0; /* Position of last space on the line */
char saveword[MAXJUST+2];
char *cp;
getdat()
{
register char ch;
register PORTS *p;
register char *q;
int eflag;
int curmin;
ULONG class,waitbits;
USHORT code;
struct RexxMsg *rexxmessage; /* incoming rexx messages */
STRPTR Arg;
x_pos = s_pos = 0;
p = port;
cp = p->line;
*cp = 0;
/* If there was a justified word left over from previous line .. put it
in here now.
*/
if(*saveword) {
q = saveword;
while(*q) {
ttputc(*q);
*cp++ = *q++;
x_pos++;
}
}
*saveword = 0;
/* Is a timeout timer required? */
curmin = 0;
if(p->flags & p_dotmr) {
curmin = p->ctime;
}
if(curmin)settimer(curmin); /* set timeout timer if required */
p->flags setbit p_dotmr;
waitbits = windbit | timerbit | keybit | rexxbit;
while(1) {
getbits = Wait(waitbits);
if(windbit & getbits) {
while(NewMessage =
(struct IntuiMessage *)GetMsg(mywindow->UserPort)) {
class = NewMessage->Class;
code = NewMessage->Code;
ReplyMsg((struct Message *)NewMessage);
if(class == CLOSEWINDOW) {
/* say a fond farewell, don't ask fer sure? */
if(done_flag) {
if(timerbit & getbits) {
WaitIO((struct IORequest *)&timermsg);
}
else {
cantimer();
}
SetWindowTitles(mywindow,(UBYTE *)"",(UBYTE *) -1L);
done(1);
}
}
}
}
if(rexxbit & getbits) {
while(rexxmessage = GetRexxMsg(rexx_host,0L)) {
if(Arg = GetRexxCommand(rexxmessage)) {
strcpy(p->line,(char *)Arg);
strcat(p->line,"\n");
ReplyRexxCommand(rexxmessage,0L,0L,0L);
goto cmd_exit;
}
else {
FreeRexxCommand(rexxmessage);
}
}
}
if(getbits & keybit) {
WaitIO((struct IORequest *)Con_Read);
ch = ichar;
Con_Read->io_Data = (APTR)&ichar;
Con_Read->io_Command = CMD_READ;
Con_Read->io_Length = 1;
SendIO((struct IORequest *)Con_Read);
if(ch == '\033') {
if(p == cport)ttputs("getdatCON\n");
else ttputs("getdatTNC\n");
}
if(charf(ch)) {
cmd_exit:
if(timerbit & getbits) {
WaitIO((struct IORequest *)&timermsg);
}
else {
if(curmin)cantimer();
}
return(true);
}
}
if(timerbit & getbits) {
WaitIO((struct IORequest *)&timermsg);
*cp = 0;
if(!(p->mode & idle))p->mode = timeout;
return (true);
}
}
}
charf(s)
unsigned char s;
{
register unsigned char ch;
register char *q,*r;
register int i;
PORTS *p;
p = port;
ch = s;
/* Ignore characters with high order bit set...they tie up the TNC */
if(ch > 0177)return(0);
*cp = ch;
if((cp == p->line + linelen - 2) || (ch == '\r')) {
do_lf:
if(ch == '\r')*cp = '\n';
*++cp = 0;
if(p->flags & p_echo)outchar('\n');
return(1);
}
if((ch >= ' ') && (ch <= 0176)) {
/*
Do justification for local user.
*/
if(p->dev == p_console) {
if(ch == ' ') {
s_pos = x_pos;
/* If the space is at exactly the point we would have justified
the line then fake a CR anyway
*/
if(x_pos == MAXLEN) {
ch = '\r';
*saveword = 0;
goto do_lf;
}
}
else {
/* It's not a space ... should we do the justify?
*/
if(x_pos == MAXLEN) {
/* This word can't be longer than MAXJUST or we just leave
it alone and let them mess up the line
*/
if((i = (MAXLEN - s_pos)) < MAXJUST) {
q = saveword;
r = &p->line[s_pos+1];
do {
*q++ = *r++;
ttputs("\b \b");
}while(--i);
*q = 0;
cp = &p->line[s_pos];
ch = '\r';
goto do_lf;
}
}
}
}
x_pos++;
if (p->flags & p_echo) ttputc(ch);
cp++;
return(0);
}
switch(ch) {
default:
break;
case 26: /* Control - Z */
cp++;
x_pos++;
break;
case '\t':
if(p->flags & p_echo) ttputc(ch);
s_pos = x_pos;
x_pos++;
cp++;
break;
case '\b':
if(cp > p->line) {
cp--;
if(p->flags & p_echo) ttputs("\b \b");
x_pos--;
/* If they wipe out a space we've got to find the previous one */
if(*cp == ' ') {
r = cp-1;
while(r > p->line) {
if(*r == ' ') break;
r--;
}
s_pos = r - p->line;
}
}
break;
case '\n':
if(cp is p->line) {
*cp = '\0';
return(1);
}
break;
}
#ifdef OLD_CODE
switch(*cp) {
default:
if (p->flags & p_echo) outchar(*cp);
cp++;
break;
case '\b':
if(cp > p->line) {
cp--;
if(p->flags & p_echo)outstr("\b \b");
}
break;
case '\n':
if(cp is p->line) {
*cp = '\0';
return(1);
}
break;
case '\0' : /* Ignore most ctl char */
case ctl_c: /* Ignore most ctl char */
case ctl_v: /* Ignore most ctl char */
case '\033':
break;
}
#endif
return(0);
}
/* replace waitcmd from mbtnc to reduce busy waits */
/* NOT NEEDED in SYSOP */
waitcmd(x)
int x;
{
}
/* Replace the pause routine so that it can be used with TNC as well
as the console. If routine times out after 2 minutes then it will
return 'Q'.
The test for optflags[2] allows the SYSOP to specify whether the system
will pause after 20 lines of output to the user.
*/
pause()
{
register char ch,*q;
ULONG class,waitbits;
USHORT code;
if(arexx_port)return(' ');
if (port->user->state & u_pause) return ' ';
/* If remote user has interrupted, then return a 'Q' anyway */
if(!optflags[2] && ((port->mode != local) || (pt_flag)))return(' ');
q = &tmpstr[0];
prtx(pausemsg);
if(port->mode != local)outchar('\n');
settimer(120); /* set timeout timer */
waitbits = windbit | timerbit | keybit;
while(1) {
getbits = Wait(waitbits);
if(windbit & getbits) {
while(NewMessage =
(struct IntuiMessage *)GetMsg(mywindow->UserPort)) {
class = NewMessage->Class;
code = NewMessage->Code;
ReplyMsg((struct Message *)NewMessage);
if(class == CLOSEWINDOW) {
/* say a fond farewell, don't ask fer sure? */
if(done_flag) {
if(timerbit & getbits) {
WaitIO((struct IORequest *)&timermsg);
}
else {
cantimer();
}
SetWindowTitles(mywindow,(UBYTE *)"",(UBYTE *) -1L);
done(1);
}
}
}
}
if(getbits & keybit) {
WaitIO((struct IORequest *)Con_Read);
ch = toupper(ichar);
Con_Read->io_Data = (APTR)&ichar;
Con_Read->io_Command = CMD_READ;
Con_Read->io_Length = 1;
SendIO((struct IORequest *)Con_Read);
if(timerbit & getbits) {
WaitIO((struct IORequest *)&timermsg);
}
else {
cantimer();
}
outchar('\n');
return(ch);
}
/* check for timeout */
if(timerbit & getbits) {
WaitIO((struct IORequest *)&timermsg);
return('Q');
}
}
}
/* Null routines from the mblog.c file.
SYSOP does not do any logging whatever (there's also a small fix in
mbinit.c to turn off all the logging flags).
It also does no monitoring.
*/
/* Define the length of a heard item. It is easier to do this and have
mbinit allocate a very small heard list than to have another version
of mbinit just for one small change.
*/
char *lgfile = 0,*monfile = 0,*hrdfile = 0;
int hrdmax = 1;
char fbb_direction;
/* Dummy fbb forwarding */
char *mbvers,*fbbvers;
fbbfwd()
{
}